﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ExtenderProvider.cs" company="Matthias Friedrich">
//   Copyright © Matthias Friedrich 2009
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace DeviceManagement
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;

	public abstract class ExtenderProvider<T> : IExtenderProvider
		where T : class
	{
		private readonly IDictionary<T, IDictionary<object, object>> extendees = new Dictionary<T, IDictionary<object, object>>();

		private readonly object syncObject = new object();

		protected ExtenderProvider()
		{
		}

		#region IExtenderProvider Members

		bool IExtenderProvider.CanExtend(object extendee)
		{
			return (extendee as T) != null;
		}

		protected virtual TResult GetProperty<TResult>(T extendee, object extenderProperty)
		{
			if (extendee == null)
			{
				throw new ArgumentNullException("extendee");
			}

			if (extenderProperty == null)
			{
				throw new ArgumentNullException("extenderProperty");
			}

			lock (this.syncObject)
			{
				if (this.extendees.ContainsKey(extendee))
				{
					if (this.extendees[extendee].ContainsKey(extenderProperty))
					{
						return (TResult)this.extendees[extendee][extenderProperty];
					}
				}
			}

			return default(TResult);
		}

		protected virtual void SetProperty(T extendee, object extenderProperty, object value)
		{
			if (extendee == null)
			{
				throw new ArgumentNullException("extendee");
			}

			if (extenderProperty == null)
			{
				throw new ArgumentNullException("extenderProperty");
			}

			lock (this.syncObject)
			{
				if (!this.extendees.ContainsKey(extendee))
				{
					this.extendees[extendee] = new Dictionary<object, object>();
				}

				IDictionary<object, object> propertyBag = this.extendees[extendee];
				propertyBag[extenderProperty] = value;
			}
		}

		#endregion
	}
}